package com.start.avue.mapper;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.start.avue.calculate.StartCalculate;
import com.start.avue.configs.StartCalculateConfig;
import com.start.avue.convert.AvueFormMapperConvert;
import com.start.common.tools.ClassTools;
import com.start.common.tools.SpringContextTools;
import com.start.common.tools.StartStreamTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class AvueDynamicMapper extends AvueDefaultMapper {
    public static final String MAPPER_TYPE = "dynamic";
    private static final String CHILDREN_KEY = "children";

    private AvueFormMapperConvert formMapperConvert;
    private List<StartAvueMapper> childrenFormMappers;
    private List<AvueColumnSummary> columnSummaries;

    @Override
    public void init(String startHomeUrl, JSONObject column, Map<String, String> headers) {
        super.init(startHomeUrl, column, headers);
        formMapperConvert = new AvueFormMapperConvert(startHomeUrl, headers);
        if (!column.containsKey("children")) {
            return;
        }
        JSONObject childrenForm = column.getJSONObject(CHILDREN_KEY);
        childrenFormMappers = formMapperConvert.getAvueMapper(childrenForm);
        columnSummaries = initSummaryColumn(childrenForm, StartCalculateConfig.getDefaultCalculateMap());
    }

    public void initSummaryColumn(Map<String, Class<? extends StartCalculate>> calculateMap) {
        JSONObject childrenForm = column.getJSONObject(CHILDREN_KEY);
        initSummaryColumn(childrenForm, calculateMap);
    }

    /**
     * 初始化需要统计的列信息
     *
     * @param childrenForm
     * @param calculateMap
     * @return
     */
    private List<AvueColumnSummary> initSummaryColumn(JSONObject childrenForm, Map<String, Class<? extends StartCalculate>> calculateMap) {
        if (!childrenForm.containsKey("showSummary")) {
            return null;
        }
        boolean showSummary = childrenForm.getBooleanValue("showSummary");
        if (!showSummary) {
            return null;
        }
        JSONArray jsonArray = childrenForm.getJSONArray("sumColumnList");
        if (jsonArray == null || jsonArray.isEmpty()) {
            return null;
        }
        return jsonArray.toJavaList(AvueColumnSummary.class).stream().filter(e -> StringUtils.isNotBlank(e.getName())).filter(StartStreamTools.distinctByKey(AvueColumnSummary::getName)).peek(e -> {
            if (StringUtils.isAllBlank(e.getType())) {
                return;
            }
            Class<? extends StartCalculate> calculateClazz = calculateMap.get(e.getType());
            if (calculateClazz == null) {
                log.error("不支持的计算方式：" + e.getName());
                return;
            }
            StartCalculate calculate = ClassTools.createObject(calculateClazz);
            assert calculate != null;
            if (calculate.autoInjectBean()) {
                SpringContextTools.autowire(calculate);
            }
            e.setCalculate(calculate);
        }).collect(Collectors.toList());
    }

    @Override
    public Object labelToValue(String label) {
        return super.labelToValue(label);
    }

    @Override
    public Object valueToLabel(Object value) {
        if (value == null) {
            return super.valueToLabel(value);
        }
        JSONArray jsonArray = objectToJSONArray(value);
        if (jsonArray == null) return super.valueToLabel(value);
        JSONArray array = formMapperConvert.convertDataToLabel(childrenFormMappers, jsonArray);
        if (array == null) return super.valueToLabel(value);
        JSONObject jsonObject = calculateSummaries(this.columnSummaries, array);
        if (jsonObject != null && !jsonObject.isEmpty()) {
            array.add(jsonObject);
        }
        return array;
    }

    /**
     * 计算统计
     *
     * @param summaries
     * @param dataArray
     * @return
     */
    private JSONObject calculateSummaries(List<AvueColumnSummary> summaries, JSONArray dataArray) {
        if (summaries == null) return null;
        if (dataArray.isEmpty()) return null;
        int size = dataArray.size();
        for (AvueColumnSummary summary : summaries) {
            if (StringUtils.isAllBlank(summary.getName())) continue;
            if (summary.getCalculate() == null) continue;
            summary.rest();
            for (int i = 0; i < size; i++) {
                JSONObject data = dataArray.getJSONObject(i);
                BigDecimal bigDecimal = data.getBigDecimal(summary.getName());
                if (bigDecimal == null) {
                    bigDecimal = new BigDecimal(0);
                }
                BigDecimal calculate = summary.getCalculate().calculate(summary.getValue(), bigDecimal, i, dataArray);
                summary.setValue(calculate);
            }
        }
        Map<String, String> map = summaries.stream().collect(Collectors.toMap(AvueColumnSummary::getName, AvueColumnSummary::getFormatValue, (e1, e2) -> e1));
        return JSONObject.from(map);
    }

}
